package db

import (
	"errors"
	"pmservice/graph/model"

	gonanoid "github.com/matoous/go-nanoid/v2"
	"gorm.io/gorm"
)

type Fac struct {
	gorm.Model
	UID      string
	Hospital string
	Name     string
	Desc     string
}

func (Fac) TableName() string {
	return "fac"
}

func (d *Fac) FromGQLNew(in *model.FacNew) {
	d.Hospital = in.Hosuid
	d.Name = in.Name
	if in.Desc != nil {
		d.Desc = *in.Desc
	}
}

func (d *Fac) FromGQLEdit(in *model.FacEdit) []string {
	fields := []string{}
	if in.Name != nil {
		d.Name = *in.Name
		fields = append(fields, "name")
	}
	if in.Desc != nil {
		d.Desc = *in.Desc
		fields = append(fields, "desc")
	}
	return fields
}

func (d *Fac) ToGQL() *model.Facility {
	return &model.Facility{
		UID:  d.UID,
		Name: d.Name,
		Desc: &d.Desc,
	}
}

func FacGet(dbs *gorm.DB, uid string) *Fac {
	d := Fac{}
	result := dbs.Where("uid=?", uid).Take(&d)
	if result.Error != nil {
		return nil
	}
	return &d
}

// 检查账号名是否已被使用
func FacExist(dbs *gorm.DB, hosuid string, except string, name string) bool {
	d := Fac{}
	result := dbs
	if except == "" {
		result = dbs.Where("name=? AND hospital=?", name, hosuid).Take(&d)
	} else {
		result = dbs.Where("name=? AND hospital=? AND uid!=?", name, hosuid, except).Take(&d)
	}
	return result.Error == nil && result.RowsAffected > 0
}

func FacNew(dbs *gorm.DB, input *model.FacNew) (*Fac, error) {
	if FacExist(dbs, input.Hosuid, "", input.Name) {
		return nil, errors.New("病区已被使用")
	}
	d := Fac{
		UID: gonanoid.Must(),
	}
	d.FromGQLNew(input)
	// 创建账号
	result := dbs.Create(&d)
	if result.Error != nil {
		return nil, result.Error
	}
	return &d, nil
}

func FacSave(dbs *gorm.DB, hosuid string, uid string, input *model.FacEdit) bool {
	if input.Name != nil && FacExist(dbs, hosuid, uid, *input.Name) {
		return false
	}
	d := Fac{}
	fields := d.FromGQLEdit(input)
	result := dbs.Where("uid=? AND hospital=?", uid, hosuid).
		Select(fields).
		Updates(&d)
	if result.Error != nil || result.RowsAffected == 0 {
		return false
	}
	return true
}

func FacDel(dbs *gorm.DB, uid string) bool {
	result := dbs.Where("uid=?", uid).Delete(&Fac{})
	return result.Error == nil && result.RowsAffected > 0
}

func FacSearch(dbs *gorm.DB, cond model.FacSearchCond) (facs []*Fac, total int64) {
	result := dbs.Where("hospital=?", cond.Hosuid)
	if cond.Name != nil {
		result = result.Where("name like ?", "%"+*cond.Name+"%")
	}

	result.Model(&Fac{}).Count(&total)
	if cond.Page != nil {
		result = result.Order("id DESC").Limit(cond.Page.Number).Offset(cond.Page.Offset).Find(&facs)
	} else {
		result = result.Order("id DESC").Find(&facs)
	}

	if result.Error != nil {
		return nil, 0
	}

	return facs, total
}
